package com.vpen.netty.demo.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.CharsetUtil;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

/**
 * 描述 客户端启动类
 *
 * @author 韦鹏
 * @date 2022/11/11 21:43
 */
public class AppClient {
    private final String host;
    private final Integer port;

    /**
     * 处理IO操作的多线程事件循环相当于一组线程池
     */
    private NioEventLoopGroup nioLoop = new NioEventLoopGroup();

    public AppClient(String host, Integer port) {
        this.host = host;
        this.port = port;
    }


    public void run() {
        try {
            doConnect(new Bootstrap(), nioLoop);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * Bootstrap: 客户端启动辅助对象
     */
    public Bootstrap doConnect(Bootstrap bootstrap, EventLoopGroup eventLoopGroup) throws InterruptedException {
        bootstrap.group(eventLoopGroup)
                .channel(NioSocketChannel.class) //实例化一个通道
                .remoteAddress(new InetSocketAddress(this.host, this.port))// 运程地址
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // 添加自定义的handler
                        ch.pipeline().addLast(new HelloWorldClientHandler());
                    }
                });//进行通道配置
        // 连接远程主机，等待连接完成
        ChannelFuture future = bootstrap.connect().sync();

//        发送给服务端
        future.channel().writeAndFlush(Unpooled.copiedBuffer("你好，服务端----来自客户端", CharsetUtil.UTF_8));

//        尝试重连
//        ChannelFuture future = bootstrap.connect().addListener((ChannelFuture futureListener)->{
//            final EventLoop eventLoop = futureListener.channel().eventLoop();
//            if (!futureListener.isSuccess()) {
//                System.out.println("连接服务器失败，5s后重新尝试连接！");
//                futureListener.channel().eventLoop().schedule(() -> doConnect(new Bootstrap(), eventLoop), 5, TimeUnit.SECONDS);
//            }
//        });

        future.channel().closeFuture().sync();

//        优雅关闭
//        eventLoopGroup.shutdownGracefully();

        return bootstrap;
    }


    public static void main(String[] args) {
        AppClient appClient = new AppClient("127.0.0.1", 18080);
        appClient.run();
    }


}
